package com.keba.lamp.common.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.keba.lamp.model.enumeration.base.FileType;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.commonmark.ext.gfm.tables.TableBlock;
import org.commonmark.node.Link;
import org.commonmark.node.Node;
import org.commonmark.renderer.html.AttributeProvider;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class MarkdownToPdf {
    private static String FONT_PATH;
    private static String BD_FONT_PATH;
    private final static Charset charset = Charset.forName("GBK");
    final static String[] colWidth = {"12%", "24%", "40%", "12%", "12%"};
    //核心线程数，核心线程默认会一直存在
    public static int corePoolSize = 10;

    //最大线程数
    public static int maximumPoolSize = 50;

    //非核心线程的线程存活时间
    public static int keepAliveTime = 10;

    /**
     * 定义一个线程池
     *
     * @return
     */
    public static ThreadPoolExecutor buildThreadPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(200)); //有界队列，容量200;
        return executor;
    }


    public MarkdownToPdf(String fontPath, String bdFontPath) {
        this.FONT_PATH = fontPath;
        this.BD_FONT_PATH = bdFontPath;
    }

    public static void create(int startPage, List<FileInfo> fileInfoList, OutputStream outputStream) throws Exception {

        /************************线程池下载图片***********************/
        ThreadPoolExecutor executorService = buildThreadPool();
        List<Future<ImageResult>> futures = new ArrayList<>();
        for (int i = 0 ; i < fileInfoList.size(); i++) {
            final int index = i;
            final String fileUrl = fileInfoList.get(i).getUrl();
            final FileType fileType = fileInfoList.get(i).getFileType();
            Future<ImageResult> submit = executorService.submit(() -> {
                try {
                    long begin = System.currentTimeMillis();
                    log.info("下载文件开始:{}", fileUrl);
                    HttpResponse httpResponse = HttpRequest.get(fileUrl).execute();
                    log.info("下载文件结束:{}, 耗时:{}", fileUrl, System.currentTimeMillis() - begin);
                    if (httpResponse.isOk()) {
                        ImageResult imageResult = new ImageResult();
                        imageResult.setIndex(index);
                        imageResult.setFileType(fileType);
                        imageResult.setFileBytes(httpResponse.bodyBytes());
                        return imageResult;
                    } else {
                        log.error("图片下载失败:{}", fileUrl);
                        return null;
                    }
                } catch (Exception e) {
                    log.error("图片下载失败", e);
                    return null;
                }
            });
            futures.add(submit);
        }
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
            throw new RuntimeException("图片下载失败");
        }
        List<ImageResult> imageList = new ArrayList<>();
        for (Future<ImageResult> future : futures) {
            try {
                ImageResult imageResult = future.get();
                if (imageResult == null) {
                    throw new RuntimeException("图片下载失败");
                }
                imageList.add(imageResult.getIndex(), imageResult);
            } catch (ExecutionException e) {
                log.error("图片下载失败:", e);
                throw new RuntimeException("图片下载失败");
            } catch (InterruptedException e) {
                throw new RuntimeException("图片下载失败");
            }
        }

        /************************开始生成PDF文档***********************/

//        if (imageList.size() == 1 && FileType.DOC.eq(imageList.get(0).getFileType())) {
//            log.info("只有一个pdf文件，直接使用该文件");
//            PDDocument subDocument = PDDocument.load(imageList.get(0).getFileBytes());
//            subDocument.save(outputStream);
//            return;
//        }

        Document document = new Document(PageSize.A4);

        PdfWriter pdfWriter = PdfWriter.getInstance(document,
                outputStream);
        // 设置页脚
        FooterEvent footerEvent = new FooterEvent(startPage);
        pdfWriter.setPageEvent(footerEvent);
        document.open();
        document.addCreationDate();

        imageList.stream().forEach(file -> {
            try {
                if (FileType.IMAGE.eq(file.getFileType())) {
                    addPage(file.getFileBytes(), document);
                } else {
                    PDDocument subDocument = PDDocument.load(new ByteArrayInputStream(file.getFileBytes()), MemoryUsageSetting.setupTempFileOnly());
                    //移除加密
                    subDocument.setAllSecurityToBeRemoved(true);
                    PDFRenderer renderer = new PDFRenderer(subDocument);
                    for (int i = 0; i < subDocument.getNumberOfPages(); i++) {
                        BufferedImage image = renderer.renderImageWithDPI(i, 150); // 设置图片分辨率为150 DPI
                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                        // 将BufferedImage写入ByteArrayOutputStream中
                        ImageIO.write(image, "jpg", byteArrayOutputStream);
                        addPage(byteArrayOutputStream.toByteArray(), document);
                    }
                    if (Objects.nonNull(subDocument)) {
                        subDocument.getDocument().close();
                        subDocument.close();
                    }
                }
            } catch (Exception ex) {
                log.error("图片转换失败", ex);
            }
        });
        document.close();
    }


    private static void addPage(byte[] fileBytes, Document document) throws IOException, DocumentException {
        Image image = Image.getInstance(fileBytes);
        float pageWidth = document.getPageSize().getWidth();
        float pageHeight = document.getPageSize().getHeight();

        // 计算图片的原始宽度和高度
        float imgWidth = image.getScaledWidth();
        float imgHeight = image.getScaledHeight();

        // 计算缩放因子，确保图片不超出页面宽度
        float scaleFactor = pageWidth / imgWidth * 0.75F;

        // 如果图片的高度超过页面高度，重新计算缩放因子
        if ((imgHeight * scaleFactor) > pageHeight * 0.75F) {
            scaleFactor = pageHeight / imgHeight * 0.75F;
        }

        // 根据缩放因子调整图片大小
        image.scaleAbsolute((float) (imgWidth * scaleFactor), (float) (imgHeight * scaleFactor));

        // 计算图片在页面上的水平居中位置
        float posX = (pageWidth - image.getScaledWidth()) / 2;
        float posY = (pageHeight - image.getScaledHeight()) / 2;

        // 将图片添加到 PDF 文档
        image.setAbsolutePosition(posX, posY);

        document.newPage();
        document.add(image);
    }


    public void create(List<String> plaintffList,
                       List<String> defendantList,
                       String htmlTableContent,
                       OutputStream outputStream) throws Exception {
        Document document = new Document(PageSize.A4);
        //1cm = 28.35磅 左右：3.18cm，上下：2.54
        document.setMargins(90, 90, 72, 72);
        PdfWriter pdfWriter = PdfWriter.getInstance(document,
                outputStream);

        // 设置页脚
        FooterEvent footerEvent = new FooterEvent(1);
        pdfWriter.setPageEvent(footerEvent);
        document.open();
        document.addCreationDate();

        BaseFont bf = BaseFont.createFont("SimSun.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font titleFont = new Font(bf, 18, Font.BOLD, BaseColor.BLACK);
        Font boldFont = new Font(bf, 12, Font.BOLD, BaseColor.BLACK);
        Font normalFont = new Font(bf, 12, Font.NORMAL, BaseColor.BLACK);
        Paragraph title = new Paragraph("证据目录", titleFont);
        title.setAlignment(com.itextpdf.text.Element.ALIGN_CENTER);
        document.add(title);
        document.add(new Paragraph("\n"));

        //1、原告信息 小四
        if (plaintffList.size() > 1) {
            for (int i = 0; i < plaintffList.size(); i++) {
                Paragraph plaintffGraph = new Paragraph();
                plaintffGraph.add(new Chunk("原告" + (i + 1) + "：", normalFont));
                plaintffGraph.add(new Chunk(plaintffList.get(i), normalFont));
                document.add(plaintffGraph);
            }
        } else {
            Paragraph plaintffGraph = new Paragraph();
            plaintffGraph.add(new Chunk("原告：", normalFont));
            plaintffGraph.add(new Chunk(plaintffList.get(0), normalFont));
            document.add(plaintffGraph);
        }
        //2、被告信息 小四
        if (defendantList.size() > 1) {
            for (int i = 0; i < defendantList.size(); i++) {
                Paragraph defendantGraph = new Paragraph();
                defendantGraph.add(new Chunk("被告" + (i + 1) + "：", normalFont));
                defendantGraph.add(new Chunk(defendantList.get(i), normalFont));
                document.add(defendantGraph);
            }
        } else {
            Paragraph defendantGraph = new Paragraph();
            defendantGraph.add(new Chunk("被告：", normalFont));
            defendantGraph.add(new Chunk(defendantList.get(0), normalFont));
            document.add(defendantGraph);
        }

        XMLWorkerHelper worker = XMLWorkerHelper.getInstance();

//        List<Extension> tableExtension = Collections.singletonList(TablesExtension.create());
//        org.commonmark.parser.Parser parser = org.commonmark.parser.Parser.builder()
//                .extensions(tableExtension)
//                .build();
//        Node node = parser.parse(markdownContent);
//        HtmlRenderer renderer = HtmlRenderer.builder()
//                .extensions(tableExtension)
//                .attributeProviderFactory(new AttributeProviderFactory() {
//                    public AttributeProvider create(AttributeProviderContext context) {
//                        return new CustomAttributeProvider();
//                    }
//                })
//                .build();
//        String htmlContent = renderer.render(node);
        String htmlContent = "<html lang=\"en\"><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + charset.name() + "\" /><body>" + htmlTableContent + "</body></html>";
        org.jsoup.nodes.Document htmlDoc = Jsoup.parse(htmlContent, "", Parser.xmlParser());
        Element element = htmlDoc.selectFirst("table");
        Elements centerEle = htmlDoc.select("center");
        //处理center标签
        if (centerEle != null) {
            for (Element center : centerEle) {
                Element parent = center.parent();
                String text = center.text();
                center.remove();
                parent.text(text);
                parent.attr("align", "center");
                parent.attr("style", "margin:0 auto;text-align:center;");
            }
        }
        if (element != null) {
            //处理表格宽度问题
            Elements elements = element.select("th");
            for (int i = 0; i < elements.size(); i++) {
                if (i < colWidth.length) {
                    elements.get(i).attr("width", colWidth[i]);
                }
            }
        }

        //处理h1~h6问题
        Elements aList = htmlDoc.select("h1 a,h2 a,h3 a,h4 a,h5 a,h6 a");
        for (Element a : aList) {
            String text = a.text();
            a.text("");
            a.appendElement("strong");
            a.child(0).text(text);
        }
        String bodyContent = htmlDoc.select("body").html();
        log.info("生成pdf原始html内容：{}", htmlDoc.select("body").html());
        worker.parseXHtml(pdfWriter, document, new ByteArrayInputStream(bodyContent.getBytes(charset))
                , new ByteArrayInputStream(DefaultStyle.DEFAULT_CSS.getBytes())
                , charset
                , new AsianFontProvider(FONT_PATH, BD_FONT_PATH));
        //3、备注
        Paragraph remark = new Paragraph("注：以上均为复印件，原件待开庭时提供", normalFont);
        remark.setAlignment(com.itextpdf.text.Element.ALIGN_LEFT);
        document.add(remark);
        document.add(new Paragraph("\n"));
        document.add(new Paragraph("\n"));
        document.add(new Paragraph("\n"));

        //4、页尾 签名 小四
        Paragraph end = new Paragraph("提交人：        ", normalFont);
        end.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT);
        document.add(end);
        document.add(new Paragraph("\n"));

        //5、页尾 日期 小四
        Paragraph date = new Paragraph("提交时间：    年    月    日", normalFont);
        date.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT);
        document.add(date);
        document.add(new Paragraph("\n"));
        document.close();
    }

    public static InputStream bufferedImageToInputStream(BufferedImage image, String formatName) throws IOException {
        // 创建输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 将BufferedImage写入ByteArrayOutputStream中
        ImageIO.write(image, formatName, byteArrayOutputStream);
        // 将ByteArrayOutputStream的内容转化为输入流
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }
    /**
     * 处理标签的属性
     */
    static class CustomAttributeProvider implements AttributeProvider {
        @Override
        public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
            //改变a标签的target属性为_blank
            if (node instanceof Link) {
                attributes.put("target", "_blank");
            }
            if (node instanceof TableBlock) {
                attributes.put("class", "ui celled table");
            }
        }

    }

    static class DefaultStyle {
        public static final String DEFAULT_CSS = "table{border-collapse:collapse;border-spacing:0;width:100%;border-bottom:1px solid #222;border-right:1px solid #222;text-align:center;margin-top:20pt;margin-bottom:20pt;}*{font-size:10.5pt;font-family:SimSun;line-height:1.8}a{text-decoration:none;color:black}td,th{border-top:1px solid #222;border-left:1px solid #222;padding:8px 0;text-align:center;white-space:normal;word-wrap:break-word;word-break:break-all;}h1,h1 a,h1 a strong{font-size:29.26pt;font-weight:bold;}h2,h2 a,h2 a strong{font-size:17.56pt;font-weight:bold;}h3,h3 a,h3 a strong{font-size:15.61pt;font-weight:bold;}h4,h4 a,h4 a strong{font-size:13.66pt;font-weight:bold;}h5,h5 a,h5 a strong{font-size:11.70pt;font-weight:bold;}h6,h6 a,h6 a strong{font-size:9.75pt;font-weight:bold;}h1,h2,h3,h4,h5,h6{font-weight:bolder}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:bolder}thead tr:nth-child(1){width:12% !important;}thead tr:nth-child(2){width:12% !important;}thead tr:nth-child(3){width:10% !important;}thead tr:nth-child(4){width:8% !important;}thead tr:nth-child(5){width:8% !important;}thead tr:nth-child(6){width:8% !important;}thead tr:nth-child(7){width:11% !important;}thead tr:nth-child(8){width:11% !important;}thead tr:nth-child(9){width:10% !important;}thead tr:nth-child(10){width:10% !important;}thead th:nth-child(1){font-weight:normal;font-size:14px;width:12% !important;}thead th:nth-child(2){font-weight:normal;font-size:14px;width:12% !important;}thead th:nth-child(3){font-weight:normal;font-size:14px;width:10% !important;}thead th:nth-child(4){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(5){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(6){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(7){font-weight:normal;font-size:14px;width:11% !important;}thead th:nth-child(8){font-weight:normal;font-size:14px;width:11% !important;}thead th:nth-child(9){font-weight:normal;font-size:14px;width:10% !important;}thead th:nth-child(10){font-weight:normal;font-size:14px;width:10% !important;}.none-border,.none-border td,.none-border th{border:none;}";
        public static final String DEFAULT_ORDER_CSS = "table{border-collapse:collapse;border-spacing:0;width:100%;border-bottom:1px solid #222;border-right:1px solid #222;margin-top:20pt;margin-bottom:20pt;}*{font-size:10.5pt;font-family:SimSun;line-height:1.8}a{text-decoration:none;color:black}td,th{border-top:1px solid #222;border-left:1px solid #222;padding:8px 0;text-align:center;white-space:normal;word-wrap:break-word;word-break:break-all;}h1,h1 a,h1 a strong{font-size:29.26pt;font-weight:bold;}h2,h2 a,h2 a strong{font-size:17.56pt;font-weight:bold;}h3,h3 a,h3 a strong{font-size:15.61pt;font-weight:bold;}h4,h4 a,h4 a strong{font-size:13.66pt;font-weight:bold;}h5,h5 a,h5 a strong{font-size:11.70pt;font-weight:bold;}h6,h6 a,h6 a strong{font-size:9.75pt;font-weight:bold;}h1,h2,h3,h4,h5,h6{font-weight:bolder}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:bolder}thead tr:nth-child(1){width:12% !important;}thead tr:nth-child(2){width:12% !important;}thead tr:nth-child(3){width:10% !important;}thead tr:nth-child(4){width:8% !important;}thead tr:nth-child(5){width:8% !important;}thead tr:nth-child(6){width:8% !important;}thead tr:nth-child(7){width:11% !important;}thead tr:nth-child(8){width:11% !important;}thead tr:nth-child(9){width:10% !important;}thead tr:nth-child(10){width:10% !important;}thead th:nth-child(1){font-weight:normal;font-size:14px;width:12% !important;}thead th:nth-child(2){font-weight:normal;font-size:14px;width:12% !important;}thead th:nth-child(3){font-weight:normal;font-size:14px;width:10% !important;}thead th:nth-child(4){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(5){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(6){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(7){font-weight:normal;font-size:14px;width:11% !important;}thead th:nth-child(8){font-weight:normal;font-size:14px;width:11% !important;}thead th:nth-child(9){font-weight:normal;font-size:14px;width:10% !important;}thead th:nth-child(10){font-weight:normal;font-size:14px;width:10% !important;}.left{width:100%;display:table:text-align:left;float:left}.right{width:100%;display:table:text-align:right;float:right}.none-border,.none-border td,.none-border th{border:none;}";
    }

    static class AsianFontProvider extends XMLWorkerFontProvider {

        private final String FONT_PATH;
        private final String BH_FONT_PATH;

        public AsianFontProvider() {
            this.FONT_PATH = "";
            this.BH_FONT_PATH = "";
        }


        public AsianFontProvider(String fontPath, String bhFontPath) {
            this.FONT_PATH = fontPath;
            this.BH_FONT_PATH = bhFontPath;

        }


        @Override
        public Font getFont(final String fontName, String encoding, float size, final int style) {
            try {
                BaseFont bfChinese;
                if (fontName.equalsIgnoreCase("simsun") && style >= 1) {
                    bfChinese = BaseFont.createFont(this.FONT_PATH, "Identity-H", false);
                    return new Font(bfChinese, size, style);
                } else {
                    bfChinese = BaseFont.createFont(this.FONT_PATH, "Identity-H", false);
                    Font font = new Font(bfChinese, size, style, BaseColor.BLACK);
                    return font;
                }
            } catch (Exception e) {
                log.error("字体异常：", e);
                return super.getFont(fontName, encoding, size, style);
            }
        }

        private static final String temp = "## <center>采购订单</center> \n" +
                "**框架协议编号：** K2007021109M362 \n" +
                "**合同编号：** C2009101055G896 \n" +
                "**甲方（委托方）：** 宁波衣加衣供应链管理有限公司 \n" +
                "**乙方（受托方）：** 广州市番禺区南村聚庆义服装厂 \n" +
                "&nbsp;&nbsp;&nbsp;&nbsp;根据《中华人民共和国合同法》等有关法律、法规的规定，甲、乙双方在平等、自愿、公平和诚实信用的基础上，经协商一致，就甲方委托乙方进行服装生产事宜，订立本采购订单。 本订单是根据甲乙双方已签订的框架协议（协议编号：K2007021109M362）基础上签订盖采购订单，采购订单和框架协议具有同等法律效力，在签订本协议前，请认真阅读框架协议内容。 \n" +
                "**第一条：订单明细**\n" +
                " 采购款数：  <u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>;采购总数：<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>;采购合计总金额：<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;102220.00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>. \n" +
                "具体采购明细如下表 \n" +
                "\n" +
                "\n" +
                "| 订单号 |品类| 款号 | 颜色 | 数量 | 单位 | 采购单价（元/单位） | 金额（元） | 交货期 | \n" +
                "| ---------- | ---- | ---- | ---- | ---- | ---- | ------------------- | ---------- | ------ | \n" +
                "| TSPO000003VF| 女装-衬衫| MJ-7P1566-1| 粉红| 2000| 件|20.00| 40000.00| 2020-09-13| \n" +
                "| TSPO000003VF| 女装-衬衫| MJ-7E176| 咖啡色| 3000| 件|20.74| 62220.00| 2020-09-20| \n" +
                "|合计金额| 102220.00|||| 大写 | 壹拾万贰仟贰佰贰拾元整||| \n" +
                "| 是否含税 | 以上价格含13.0%税点 |||||||| \n" +
                "| 备注 | MJ-7E176款 17加工费+0.64朴+0.52纽扣+拷贝纸 防潮珠 胶袋 备用袋0.19=18.35*1.13=20.74元 \n MJ-7P1566-1 17款加工费+0.52朴+0.19拷贝纸 防潮珠 胶袋 备用袋=17.71*1.13=20元 每月25号完成交货，次月20号对账。 |||||||| \n" +
                "**注明：尺码详细表以下方附件为准或以甲乙双方其他书面约定为准。** \n" +
                "**备注**：\n" +
                "1，乙方负责送货至广州番禺大石汇江MJ 笕尚公司收货仓,\n" +
                "2，按工艺单生产要求，乙方负责从裁、印花、车缝、烫、包装的生产工序。乙方负责成衣交货运费和车缝线的费用。 \n" +
                "3，乙方交货30日后，甲方付清加工货款。 第三条 效力 \n" +
                "3.1.本订单自甲乙双方签字盖章之日起生效，一式两份，甲乙双方各执一份，具有同等法律效力。 \n" +
                "3.2.本订单是《服装定作合作协议》不可分割的一部分，与其具有同等法律效力。本订单与《服装定作合作协议》有不一致的地方，以本订单为准。";


        private static final String order = " ###  <center> 宁波衣加衣供应链管理有限公司 </center>\n" +
                "\n" +
                "####  <center> 成衣加工对账单 </center>\n" +
                "\n" +
                "\n" +
                "\n" +
                "|      <span class='left'>成衣厂</span>    ||||  <span class='right'>广州市利美服装加工厂</span>          |||||              |||||      |||\n" +
                "| -------- | ------ | -------- | ------------------ | ---------- | ---------- | -------- | ------ | ---- | ------------ | ---------- | ---------------- | -------- | ------ | ---- | ---- | -------- |\n" +
                "| 产品名称 | 波段   | 产品款号 | 订单款号           | 交货时间   | 合同时间   | 定作方式 | 下单数 | 裁数 | 裁数装箱单数 | 正品入库数 | 合同单价(不含税) | 贷款金额 | 快递费 | 扣款 | 退货 | 结算金额 |\n" +
                "| 男装夹克 | 0908-1 | 6139043  | smouter07200807357 | 2020/10/25 | 2020/10/18 | CMT      | 100    |      | 142          | 142        | 21.5             | 3053.00  |        |      |      |          |\n" +
                "| 男装夹克 | 0908-5 | 6166282  | smouter07200807373 | 2020/11/7  | 2020/10/27 | CMT      | 150    |      | 161          | 161        | 21.5             | 3461.50  |        |      |      |          |\n" +
                "| 男装夹克 | 0908-5 | 6200485  | smouter07200807373 | 2020/11/15 | 2020/11/4  | CMT      | 200    |      | 203          | 203        | 21.5             | 4364.50  |        |      |      |          |";

        private static final String html = "<h3 align=\"center\" style=\"margin:0 auto;text-align:center;line-height: 1.5\">宁波衣加衣供应链管理有限公司</h3>\n" +
                "<h4 align=\"center\" style=\"margin:0 auto;text-align:center;line-height: 1.5\">成衣加工对账单</h4>\n" +
                "<table>\n" +
                "    <thead>\n" +
                "    <tr>\n" +
                "        <th align=\"right\" style=\"text-align: right\" colspan=\"4\" >成衣厂：</th>\n" +
                "        <th align=\"left\" style=\"text-align: left;padding-left:3px;\" colspan=\"5\">广州市利美服装加工厂</th>\n" +
                "        <th colspan=\"5\" ></th>\n" +
                "        <th colspan=\"3\"></th>\n" +
                "    </tr>\n" +
                "    </thead>\n" +
                "    <tbody>\n" +
                "    <tr>\n" +
                "        <td>产品名称</td>\n" +
                "        <td>波段</td>\n" +
                "        <td>产品款号</td>\n" +
                "        <td>订单款号</td>\n" +
                "        <td>交货时间</td>\n" +
                "        <td>合同时间</td>\n" +
                "        <td>定作方式</td>\n" +
                "        <td>下单数</td>\n" +
                "        <td>裁数</td>\n" +
                "        <td>裁数装箱单数</td>\n" +
                "        <td>正品入库数</td>\n" +
                "        <td>合同单价(不含税)</td>\n" +
                "        <td>贷款金额</td>\n" +
                "        <td>快递费</td>\n" +
                "        <td>扣款</td>\n" +
                "        <td>退货</td>\n" +
                "        <td>结算金额</td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td>男装夹克</td>\n" +
                "        <td>0908-1</td>\n" +
                "        <td>6139043</td>\n" +
                "        <td>smouter07200807357</td>\n" +
                "        <td>2020/10/25</td>\n" +
                "        <td>2020/10/18</td>\n" +
                "        <td>CMT</td>\n" +
                "        <td>100</td>\n" +
                "        <td></td>\n" +
                "        <td>142</td>\n" +
                "        <td>142</td>\n" +
                "        <td>21.5</td>\n" +
                "        <td>3053.00</td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td>男装夹克</td>\n" +
                "        <td>0908-5</td>\n" +
                "        <td>6166282</td>\n" +
                "        <td>smouter07200807373</td>\n" +
                "        <td>2020/11/7</td>\n" +
                "        <td>2020/10/27</td>\n" +
                "        <td>CMT</td>\n" +
                "        <td>150</td>\n" +
                "        <td></td>\n" +
                "        <td>161</td>\n" +
                "        <td>161</td>\n" +
                "        <td>21.5</td>\n" +
                "        <td>3461.50</td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td>男装夹克</td>\n" +
                "        <td>0908-5</td>\n" +
                "        <td>6200485</td>\n" +
                "        <td>smouter07200807373</td>\n" +
                "        <td>2020/11/15</td>\n" +
                "        <td>2020/11/4</td>\n" +
                "        <td>CMT</td>\n" +
                "        <td>200</td>\n" +
                "        <td></td>\n" +
                "        <td>203</td>\n" +
                "        <td>203</td>\n" +
                "        <td>21.5</td>\n" +
                "        <td>4364.50</td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "        <td></td>\n" +
                "    </tr>\n" +
                "    </tbody>\n" +
                "</table>" +
                "<table style=\"border:none !important;border-color:#fff;margin-top: 60px;\" class=\"none-border\">\n" +
                "    <tr>\n" +
                "        <td align=\"left\" style=\"text-align: left !important;border:none !important;border-color:#fff;\">\n" +
                "            甲方：${data.partyAName}\n" +
                "        </td>\n" +
                "        <td align=\"left\" style=\"text-align: left !important;border:none !important;border-color:#fff;\">\n" +
                "            乙方：${data.partyBName}\n" +
                "        </td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td align=\"left\" style=\"text-align: left !important;border:none !important;border-color:#fff;\">\n" +
                "            甲方盖章：\n" +
                "        </td>\n" +
                "        <td align=\"left\" style=\"text-align: left !important;border:none !important;border-color:#fff;\">\n" +
                "            乙方盖章：\n" +
                "        </td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td align=\"left\" style=\"text-align: left !important;border:none !important;border-color:#fff;\">\n" +
                "            日期：\n" +
                "        </td>\n" +
                "        <td align=\"left\" style=\"text-align: left !important;border:none !important;border-color:#fff;\">\n" +
                "            日期：\n" +
                "        </td>\n" +
                "    </tr>\n" +
                "</table>";

        public static void main(String[] args) {
            String simSunPath = "/Users/wangchaowu/idea_workspace/lamp-max-column/lamp-public/lamp-common/src/main/resources/SimSun.ttf";
            String simsunbdPath = "/Users/wangchaowu/idea_workspace/lamp-max-column/lamp-public/lamp-common/src/main/resources/simsunbd.ttf";
            try {
                MarkdownToPdf pdf = new MarkdownToPdf(simSunPath, simsunbdPath);

                List<String> imageUrlList = new ArrayList<>();
                imageUrlList.add("https://tangyh.top/images/logo.png");
                imageUrlList.add("https://tangyh.top/images/logo.png");
                imageUrlList.add("https://tangyh.top/images/logo.png");
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                ZipOutputStream zos = new ZipOutputStream(outputStream);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

                MarkdownToPdf.FileInfo fileInfo = new MarkdownToPdf.FileInfo();
                fileInfo.setFileType(FileType.IMAGE);
                fileInfo.setUrl("https://tangyh.top/images/logo.png");

                MarkdownToPdf.FileInfo fileInfo1 = new MarkdownToPdf.FileInfo();
                fileInfo1.setFileType(FileType.DOC);
                fileInfo1.setUrl("https://michi-product.oss-cn-shanghai.aliyuncs.com/1/COMPLAINT__EVIDENCE__FILE/2025/05/24/ff267d2d05b94d0ab5cb2ac58b5b4dbf.pdf");

                pdf.create(1, Lists.newArrayList(fileInfo, fileInfo1,fileInfo,fileInfo1), byteArrayOutputStream);

                ZipEntry zipEntry = new ZipEntry("证据图片.pdf");
                zos.putNextEntry(zipEntry);
                byte[] byteArray = byteArrayOutputStream.toByteArray();
                zos.write(byteArray);
                zos.closeEntry();
                zos.flush();
                FileUtil.writeBytes(outputStream.toByteArray(), "/Users/wangchaowu/Desktop//证据图片123.zip");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public void createPdf(List<String> plaintffList,
                          List<String> plaintffAgentList,
                          List<String> defendantList,
                          List<String> defendantAgentList,
                          LinkedHashMap<String, String> linkedHashMap,
                          OutputStream outputStream) {
        try {
            BaseFont bf = BaseFont.createFont("SimSun.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            Font titleFont = new Font(bf, 18, Font.BOLD, BaseColor.BLACK);
            Font boldFont = new Font(bf, 12, Font.BOLD, BaseColor.BLACK);
            Font normalFont = new Font(bf, 12, Font.NORMAL, BaseColor.BLACK);
            Document document = new Document();
            PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
            //1cm = 28.35磅 左右：3.18cm，上下：2.54
            document.setMargins(90, 90, 72, 72);

            // 设置页脚
            FooterEvent footerEvent = new FooterEvent(1);
            pdfWriter.setPageEvent(footerEvent);
            document.open();
            //0、标题 小二 加粗 居中
            Paragraph title = new Paragraph("民事起诉状", titleFont);
            title.setAlignment(com.itextpdf.text.Element.ALIGN_CENTER);
            document.add(title);
            document.add(new Paragraph("\n"));
            //1、原告信息 小四 加粗
            if (plaintffList.size() > 1) {
                for (int i = 0; i < plaintffList.size(); i++) {
                    Paragraph plaintffGraph = new Paragraph();
                    plaintffGraph.setFirstLineIndent(25F);
                    plaintffGraph.add(new Chunk("原告" + (i + 1) + "：", boldFont));
                    String plaintffName = plaintffList.get(i);
                    plaintffGraph.add(new Chunk(StringUtils.isBlank(plaintffName) ? "" : plaintffName, normalFont));
                    document.add(plaintffGraph);
                }
            } else {
                Paragraph plaintffGraph = new Paragraph();
                plaintffGraph.setFirstLineIndent(25F);
                plaintffGraph.add(new Chunk("原告：", boldFont));
                String plaintffName = plaintffList.get(0);
                plaintffGraph.add(new Chunk(StringUtils.isBlank(plaintffName) ? "" : plaintffName, normalFont));
                document.add(plaintffGraph);
            }
            document.add(new Paragraph("\n"));

            if (CollectionUtil.isNotEmpty(plaintffAgentList)) {
                //1.1、代理人信息 小四 加粗
                if (plaintffAgentList.size() > 1) {
                    for (int i = 0; i < plaintffAgentList.size(); i++) {
                        Paragraph agentGraph = new Paragraph();
                        agentGraph.setFirstLineIndent(25F);
                        agentGraph.add(new Chunk("委托代理人" + (i + 1) + "：", boldFont));
                        String agentName = plaintffAgentList.get(i);
                        agentGraph.add(new Chunk(StringUtils.isBlank(agentName) ? "" : agentName, normalFont));
                        document.add(agentGraph);
                    }
                } else {
                    Paragraph agentGraph = new Paragraph();
                    agentGraph.setFirstLineIndent(25F);
                    agentGraph.add(new Chunk("委托代理人：", boldFont));
                    String agentName = plaintffAgentList.get(0);
                    agentGraph.add(new Chunk(StringUtils.isBlank(agentName) ? "" : agentName, normalFont));
                    document.add(agentGraph);
                }
                document.add(new Paragraph("\n"));
            }

            //2、被告信息 小四 加粗
            if (defendantList.size() > 1) {
                for (int i = 0; i < defendantList.size(); i++) {
                    Paragraph defendantGraph = new Paragraph();
                    defendantGraph.setFirstLineIndent(25F);
                    defendantGraph.add(new Chunk("被告" + (i + 1) + "：", boldFont));
                    String defendantName = defendantList.get(i);
                    defendantGraph.add(new Chunk(StringUtils.isBlank(defendantName) ? "" : defendantName, normalFont));
                    document.add(defendantGraph);
                }
            } else {
                Paragraph defendantGraph = new Paragraph();
                defendantGraph.setFirstLineIndent(25F);
                defendantGraph.add(new Chunk("被告：", boldFont));
                String defendantName = defendantList.get(0);
                defendantGraph.add(new Chunk(StringUtils.isBlank(defendantName) ? "" : defendantName, normalFont));
                document.add(defendantGraph);
            }
            document.add(new Paragraph("\n"));

            if (CollectionUtil.isNotEmpty(defendantAgentList)) {
                //1.1、代理人信息 小四 加粗
                if (defendantAgentList.size() > 1) {
                    for (int i = 0; i < defendantAgentList.size(); i++) {
                        Paragraph agentGraph = new Paragraph();
                        agentGraph.setFirstLineIndent(25F);
                        agentGraph.add(new Chunk("委托代理人" + (i + 1) + "：", boldFont));
                        String agentName = defendantAgentList.get(i);
                        agentGraph.add(new Chunk(StringUtils.isBlank(agentName) ? "" : agentName, normalFont));
                        document.add(agentGraph);
                    }
                } else {
                    Paragraph agentGraph = new Paragraph();
                    agentGraph.setFirstLineIndent(25F);
                    agentGraph.add(new Chunk("委托代理人：", boldFont));
                    String agentName = defendantAgentList.get(0);
                    agentGraph.add(new Chunk(StringUtils.isBlank(agentName) ? "" : agentName, normalFont));
                    document.add(agentGraph);
                }
                document.add(new Paragraph("\n"));
            }

            //3、起诉状内容 小四
            for (String key : linkedHashMap.keySet()) {
                if (!"法院".equals(key)) {
                    //标题
                    document.add(new Paragraph(key + "：", boldFont));

                    String value = linkedHashMap.get(key);
                    String[] strings = value.split("\n");
                    for (String s : strings) {
                        //内容
                        Paragraph paragraph = new Paragraph(s, normalFont);
                        paragraph.setFirstLineIndent(25F);
                        document.add(paragraph);
                        //空一行
                    }
                } else {
                    //标题
                    Paragraph courtTitle = new Paragraph("此致", boldFont);
                    courtTitle.setFirstLineIndent(25F);
                    document.add(courtTitle);

                    String value = linkedHashMap.get(key);
                    //内容
                    Paragraph paragraph = new Paragraph(value, normalFont);
                    paragraph.setFirstLineIndent(25F);
                    document.add(paragraph);
                }
                //空一行
                document.add(new Paragraph("\n"));
            }

            //4、页尾 签名 小四
            Paragraph end = new Paragraph("起诉人（签名）：        ", normalFont);
            end.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT);
            document.add(end);
            document.add(new Paragraph("\n"));

            //5、页尾 日期 小四
            Paragraph date = new Paragraph("年    月    日", normalFont);
            date.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT);
            document.add(date);
            document.add(new Paragraph("\n"));
            document.close();
        } catch (Exception e) {
            log.error("生成pdf失败", e);
        }
    }

    public static ByteArrayOutputStream createPdf(JSONObject jsonObject) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            BaseFont bf = BaseFont.createFont("SimSun.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            Font titleFont = new Font(bf, 18, Font.BOLD, BaseColor.BLACK);
            Font boldFont = new Font(bf, 12, Font.BOLD, BaseColor.BLACK);
            Font normalFont = new Font(bf, 12, Font.NORMAL, BaseColor.BLACK);
            Document document = new Document();
            PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
            //1cm = 28.35磅 左右：3.18cm，上下：2.54
            document.setMargins(90, 90, 72, 72);

            // 设置页脚
            FooterEvent footerEvent = new FooterEvent(1);
            pdfWriter.setPageEvent(footerEvent);
            document.open();
            Paragraph title = new Paragraph("民事起诉状", titleFont);
            title.setAlignment(com.itextpdf.text.Element.ALIGN_CENTER);
            document.add(title);
            document.add(new Paragraph("\n"));
            Paragraph plattf = new Paragraph();
            plattf.setFirstLineIndent(25F);
            plattf.add(new Chunk("原告：", boldFont));
            plattf.add(new Chunk("姓名：姜孝广，性别：男，民族：汉，出生于1987年11月9日，住址：湖北省阳新县白沙镇四丰村下片下新屋组23号，身份证号码：42022198711090430，联系方式：15968786611。", normalFont));
            document.add(plattf);
            document.add(new Paragraph("\n"));

            Paragraph defend = new Paragraph();
            defend.setFirstLineIndent(25F);
            defend.add(new Chunk("被告：", boldFont));
            defend.add(new Chunk("姓名：王莹，性别：男，民族：汉，出生于1983年7月16日，住址：黑龙江省宾县宾州镇胜利街三委二十一组，身份证号码：230125198307165718，联系方式：153 3440 4443。", normalFont));
            document.add(defend);
            document.add(new Paragraph("\n"));

            for (String key : jsonObject.keySet()) {
                //标题
                document.add(new Paragraph(key + "：", boldFont));

                String value = jsonObject.getString(key);
                String[] strings = value.split("\n");
                for (String s : strings) {
                    //内容
                    Paragraph paragraph = new Paragraph(s, normalFont);
                    paragraph.setFirstLineIndent(25F);
                    document.add(paragraph);
                    //空一行
                }
                document.add(new Paragraph("\n"));
            }
            Paragraph end = new Paragraph("起诉人（签名）：        ", normalFont);
            end.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT);
            document.add(end);
            document.add(new Paragraph("\n"));


            Paragraph date = new Paragraph("年    月    日", normalFont);
            date.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT);
            document.add(date);
            document.add(new Paragraph("\n"));
            document.close();
        } catch (Exception e) {
            log.error("生成pdf失败", e);
        }
        return outputStream;
    }

    @Data
    public static class ImageResult {
        private Integer index;
        private byte[] fileBytes;
        private FileType fileType;
    }


    @Data
    public static class FileInfo {
        private String url;
        private FileType fileType;
    }
}
